using System.Collections.Generic;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Callbacks;
using UnityEngine;

namespace Super
{
	/// <summary>
	/// 重载脚本管理器
	/// 脚本重新加载后执行管理器methods中的方法
	/// 因为序列化委托是很难的，所以用这样的方法实现重载委托
	/// </summary>
	public class ReloadScriptManager : SaveSingle<ReloadScriptManager>
	{
		public Dictionary<string, List<object>> methods = new Dictionary<string, List<object>>();

		/// <summary>
		/// 增加回调方法，方法必须存在CommonUtil脚本中
		/// </summary>
		/// <param name="methodName">方法名称</param>
		/// <param name="arguments">参数列表</param>
		/// <param name="isSave">是否保存数据</param>
		public void AddMethod(string methodName, List<object> arguments, bool isSave)
		{
			methods[methodName] = arguments;

			if (isSave)
				SaveData();
		}

		/// <summary>
		/// 重编译脚本后回调的属性
		/// </summary>
		[DidReloadScripts]
		public static void OnDidReloadScripts()
		{
			TryAddDefineSymbol("spine-unity", "SPINE_PACKAGE");
			TryExecuteMethods();
		}

		/// <summary>
		/// 尝试执行已添加的方法
		/// </summary>
		public static void TryExecuteMethods()
		{
			if (Application.isPlaying || Ins.methods.Count == 0)
			{
				return;
			}

			foreach (var item in Ins.methods.Keys)
			{
				string methodName = item;
				List<object> arguments = Ins.methods[item];

				System.Type type = typeof(MethodCore);
				type.GetMethod(methodName)?.Invoke(null, arguments.ToArray());
			}

			Ins.methods.Clear();
			SaveData();
		}

		/// <summary>
		/// 尝试添加自定义宏，已启动某些框架脚本
		/// </summary>
		/// <param name="assemblyName"></param>
		/// <param name="symbol"></param>
		public static bool TryAddDefineSymbol(string assemblyName, string symbol)
		{
			if (!GlobalUtil.CheckAssemblyExistByName(assemblyName))
				return false;

			BuildTargetGroup buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup;
			string symbols = PlayerSettings.GetScriptingDefineSymbols(NamedBuildTarget.FromBuildTargetGroup(buildTargetGroup));
			if (!symbols.Contains(symbol))
			{
				var newSymbols = symbols + ";" + symbol;
				PlayerSettings.SetScriptingDefineSymbols(NamedBuildTarget.FromBuildTargetGroup(buildTargetGroup), newSymbols);
				LogUtil.Log(LogType.Normal, LogCategory.Default, $"向当前平台的ScriptingDefineSymbols添加了{symbol}");
			}
			return true;
		}
	}

}
